object Demo17NoneNilNullNothingUnit {
  // Null null Nil Nothing None Unit
  def main(args: Array[String]): Unit = {
    // 1、Null and null
    // Null是一个trait
    // null是Null的实例
    def tryit(thing: Null): Unit = {
      println("That worked!")
    }
    //            tryit("hey")

    val someRef: String = null
    //    tryit(someRef)

    tryit(null)

    val nullRef: Null = null
    tryit(nullRef)

    // 2、Nil 空的列表
    val nil: Nil.type = Nil
    println(nil)
    println(nil.length)

    // 3、Nothing
    /**
     * trait ：scala中的接口 但又像抽象类
     * Nothing是一个trait。它继承了Any类。Any是整个Scala类型系统的超类。
     * Any可以引用对象类型以及诸如普通的整数或双精度的值。
     * Nothing是一切类型的子类。
     * Nothing没有具体的实例。
     * Nothing是List的子类，它是String的子类，它是Int的子类型，它是YourOwnCustomClass的子类。
     */

    val ints: List[Any] = List[Int](1, 2, 3, 4, 5)

    val emptyStringList: List[StuL] = List[Nothing]()

    val f: List[Q] = List[Nothing]()

    val emptyIntList: List[Int] = List[Nothing]()

    //        val emptyStringList: List[String] = List[Nothing]("abc")


    // 4、None
    /**
     * 当你写一个函数，遇到没有什么实用价值的情况时，你会怎么做？
     * 通常有几种方法来处理它：
     * 1、你可以返回null，但是这会导致问题。
     * 如果调用者不希望得到null，那么当他尝试使用它时可能会面临NullPointerException
     * 否则调用者必须检查null
     * 一些函数不会返回null，但有些函数可能会。
     * 作为一个调用者，他不知道那些函数会返回null 哪些不会。
     *
     * 2、使用throws关键字，作为异常抛出。
     * 需要用try / catch处理
     * 通常希望在真正发生异常的情况下才使用try/catch
     * 而不仅仅是为了处理一个普通的无结果的情况
     *
     * 3、Scala中的方式。
     * 如果你想返回一个字符串
     * 但你知道你可能无法返回一个合理的值
     * 你可以返回一个Option[String]
     */

    val s: String = null
    if (s != null) {

      s.split(",")
    }

    def getAStringMaybe(num: Int): Option[String] = {
      if (num >= 0) {
        Some("A positive number!")
      }
      else {
        None
      } // A number less than 0?  Impossible!
    }

    val num: Int = 100
    getAStringMaybe(num) match {
      case Some(str) => println(str)
      case None => println("No string!")
    }

    // 5、Unit 相当于Java中的void，表示函数不返回任何值
  }

}
